package top.hmtools;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.ansj.lucene5.AnsjAnalyzer;
import org.ansj.lucene5.AnsjAnalyzer.TYPE;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import top.hmtools.beans.DivisionBean;
import top.hmtools.dictionary.Dictionary;
import top.hmtools.enums.EDataVersion;

/**
 * 本工具的主入口对象类
 * @author Jianghaibo
 *
 */
public class GBT2260 {
    
    private static String luceneTmpFilePath =System.getProperty("user.dir")+"/GBT2260/";
    
    private static Analyzer analyzer = new AnsjAnalyzer(TYPE.index_ansj);

    /**
     * 初始化，自动选择最新的行政地区信息字典
    * 方法说明：                    init
    * 输入参数说明：           
    * 输出参数说明：           void
    *
    *
     */
    public static void init(){
        Dictionary.init();
        List<DivisionBean> list = Dictionary.getAll();
        try {
            addToLucene(list.toArray(new DivisionBean[0]));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 初始化，手工指定行政地区信息字典路径
    * 方法说明：                    init
    * 输入参数说明：           @param luceneTmpPath
    * 输入参数说明：           @param dataFilePath
    * 输出参数说明：           void
    *
    *
     */
    public static void init(String luceneTmpPath,String dataFilePath){
        try {
            init(luceneTmpPath,new FileInputStream(dataFilePath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 初始化，手工选择本工程中已有的行政地区信息字典
    * <br>方法说明：                    init
    * <br>输入参数说明：           @param luceneTmpPath lucene文件存储路径
    * <br>输入参数说明：           @param dataVersion 行政区域版本
    * <br>输出参数说明：           void
    *
    *
     */
    public static void init(String luceneTmpPath,EDataVersion dataVersion){
        if(luceneTmpPath != null && luceneTmpPath.length()>0){
            luceneTmpFilePath = luceneTmpPath;
        }
        Dictionary.init(dataVersion);
        List<DivisionBean> list = Dictionary.getAll();
        try {
            addToLucene(list.toArray(new DivisionBean[0]));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 初始化
    * <br>方法说明：                    init
    * <br>输入参数说明：           @param luceneTmpPath lucene文件存储路径
    * <br>输入参数说明：           @param inputStream
    * <br>输出参数说明：           void
    *
    *
     */
    public static void init(String luceneTmpPath,InputStream inputStream){
        if(luceneTmpPath != null && luceneTmpPath.length()>0){
            luceneTmpFilePath = luceneTmpPath;
        }
        Dictionary.init(inputStream);
        List<DivisionBean> list = Dictionary.getAll();
        try {
            addToLucene(list.toArray(new DivisionBean[0]));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 添加行政地区信息到Lucene
    * 方法说明：                    addToLucene
    * 输入参数说明：           @param beans
    * 输入参数说明：           @throws IOException
    * 输出参数说明：           void
    *
    *
     */
    private static void addToLucene(DivisionBean... beans) throws IOException {
        final Path path = Paths.get(luceneTmpFilePath);

        Directory directory = FSDirectory.open(path);
//        Analyzer analyzer = new StandardAnalyzer();

        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
        indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE);

        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
        for (DivisionBean bean : beans) {

            Document document = new Document();
            document.add(new TextField("code", bean.getCode().toString(),Field.Store.YES));
            document.add(
                    new TextField("content", bean.toString(), Field.Store.YES));

            indexWriter.addDocument(document);
        }
        indexWriter.close();
    }
    
    /**
     * 通过code获取对应的行政地区完整信息
    * 方法说明：                    getByCode
    * 输入参数说明：           @param code
    * 输入参数说明：           @return
    * 输出参数说明：           DivisionBean
    *
    *
     */
    public static DivisionBean getByCode(String code){
        return Dictionary.getByCode(code);
    }
    
    /**
     * 根据名字获取所有
    * 方法说明：                    getSomeByName
    * 输入参数说明：           @param name
    * 输入参数说明：           @param size
    * 输入参数说明：           @return
    * 输入参数说明：           @throws IOException
    * 输入参数说明：           @throws ParseException
    * 输出参数说明：           List<DivisionBean>
    *
    *
     */
    public static List<DivisionBean> getSomeByName(String name,int size){
        if(null == name || "".equals(name)){
            return null;
        }
        
        List<DivisionBean> result = new ArrayList<DivisionBean>();
        try {
            final Path path = Paths.get(luceneTmpFilePath);
            Directory directory = FSDirectory.open(path);
//            Analyzer analyzer = new StandardAnalyzer();
            
            IndexReader indexReader = DirectoryReader.open(directory);
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            
            // 单条件
            QueryParser queryParser = new QueryParser("content", analyzer);
            Query query = queryParser.parse(name);
            
            TopDocs topDocs = indexSearcher.search(query, size);
            
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {
                Document document = indexSearcher.doc(scoreDoc.doc);
                String code = document.get("code");
                DivisionBean bean = Dictionary.getByCode(code);
                result.add(bean);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return result;
    }
    
    /**
     * 根据名称获取一条行政地区信息
    * 方法说明：                    getByName
    * 输入参数说明：           @param name
    * 输入参数说明：           @return
    * 输出参数说明：           DivisionBean
    *
    *
     */
    public static DivisionBean getByName(String name){
        List<DivisionBean> some = getSomeByName(name,1);
        if(some == null || some.size()<1){
            return null;
        }else{
            return some.get(0);
        }
    }
    
    /**
     * 获取所有省份信息
    * <br>方法说明：                    getAllProvince
    * <br>输入参数说明：           
    * <br>@return
    * <br>输出参数说明：
    * <br>List<DivisionBean>           
    *
     */
    public static List<DivisionBean> getAllProvince(){
        return Dictionary.getAllProvince();
    }
}
